#include "segmento2d.h"

Segmento2d::Segmento2d()
{

}

Segmento2d::Segmento2d(Punto2d p1, Punto2d p2)
{
    this->p1 = p1;
    this->p2 = p2;
}

Segmento2d::Segmento2d(int x1, int y1, int x2, int y2)
{
    this->p1.setCoordenadas(x1, y1);
    this->p2.setCoordenadas(x2, y2);
}

Segmento2d::Segmento2d(Punto2d p1, Vector2d direccion)
{
    this->p1 = p1;
    this->p2 = direccion.trasladarPunto(p1);
}

QString Segmento2d::toString() const
{
    return QString("%1, %2").arg(p1.toString()).arg(p2.toString());
}

Punto2d Segmento2d::getP1() const
{
    return p1;
}

void Segmento2d::setP1(Punto2d p1)
{
    this->p1 = p1;
}

Punto2d Segmento2d::getP2() const
{
    return p2;
}

void Segmento2d::setP2(Punto2d p2)
{
    this->p2 = p2;
}

bool Segmento2d::contiene(Punto2d punto) const
{
    if (!getRecta().contiene(punto)) {
        return false;
    }
    Vector2d v1 = Vector2d(getP1(), punto);
    Vector2d v2 = Vector2d(getP2(), punto);
    return !Angulo::sonIguales(v1.getAngulo(), v2.getAngulo());
}

Punto2d Segmento2d::getCentro() const
{
    return Punto2d(
            (p1.getX() + p2.getX()) / 2,
            (p1.getY() + p2.getY()) / 2);
}

void Segmento2d::desplazar(double dx, double dy)
{
    p1.setCoordenadas(p1.getX() + dx, p1.getY() + dy);
    p2.setCoordenadas(p2.getX() + dx, p2.getY() + dy);
}

void Segmento2d::girar(Angulo angulo)
{
    Punto2d centro = getCentro();
    Vector2d v1 = Vector2d(centro, p1);
    Vector2d v2 = Vector2d(centro, p2);
    v1.setAngulo(Angulo::suma(v1.getAngulo(), angulo));
    v2.setAngulo(Angulo::suma(v2.getAngulo(), angulo));
    p1 = v1.trasladarPunto(centro);
    p2 = v2.trasladarPunto(centro);
}

Recta2d Segmento2d::getRecta() const
{
    return Recta2d(p1, p2);
}

Punto2d Segmento2d::interseccion(const Segmento2d& otroSegmento) const
{
    Recta2d linea = getRecta();
    Recta2d otraLinea = otroSegmento.getRecta();
    Punto2d interseccion = linea.interseccion(otraLinea);
    if (!interseccion.esValido()) {
        return interseccion;
    }
    if (this->contiene(interseccion) && otroSegmento.contiene(interseccion)) {
        return interseccion;
    } else {
        return Punto2d::getPuntoInvalido();
    }
}

Punto2d Segmento2d::interseccion(const Recta2d& recta) const
{
    Punto2d interseccion = getRecta().interseccion(recta);
    if (!interseccion.esValido()) {
        return interseccion;
    }

    if (!this->contiene(interseccion)) {
        return Punto2d::getPuntoInvalido();
    }

    return interseccion;
}